package com.clei.Y2023.M09.D15;

import com.clei.utils.PrintUtil;

import java.io.Closeable;
import java.io.IOException;

/**
 * @author Y
 * @date 2023-09-15
 **/
public class CloseableTest {

    public static void main(String[] args) {
        // new  正常操作
        try (Door door = new Door("1-1")) {
            PrintUtil.log("正常操作");
        } catch (Exception e) {
            PrintUtil.log("operation error ", e);
        } finally {
            PrintUtil.log("finally");
        }

        // new 异常操作
        try (Door door = new Door("2-1")) {
            PrintUtil.log("异常操作");
            throw new RuntimeException("自抛异常");
        } catch (Exception e) {
            PrintUtil.log("operation error ", e);
        } finally {
            PrintUtil.log("finally");
        }

        // get  正常操作
        try (Door door = getDoor("3-1")) {
            PrintUtil.log("正常操作");
        } catch (Exception e) {
            PrintUtil.log("operation error ", e);
        } finally {
            PrintUtil.log("finally");
        }

        // get  正常操作 多个
        try (Door door1 = getDoor("4-1");
             Door door2 = getDoor("5-1")) {
            PrintUtil.log("正常操作");
        } catch (Exception e) {
            PrintUtil.log("operation error ", e);
        } finally {
            PrintUtil.log("finally");
        }

        // get 复制 正常操作 多个
        try (Door door1 = getDoor("6-1");
             // 这里只是一个声明赋值 之后也会执行close操作
             Door door2 = door1) {
            PrintUtil.log("正常操作");
        } catch (Exception e) {
            PrintUtil.log("operation error ", e);
        } finally {
            PrintUtil.log("finally");
        }

        // 总结
        // 1. 只要是在try()里声明的，不管是new的还是get的，不管一个或多个，不管是否有异常，最后都会执行close
        // 2. 执行顺序是 try() -> try{} -> Closeable.close() -> finally
        // 3. Stream多次关闭是没问题的
    }

    /**
     * getDoor
     *
     * @param code code
     * @return Door
     */
    private static Door getDoor(String code) {
        return new Door(code);
    }
}

/**
 * @author Y
 * @date 2023-09-15
 **/
class Door implements Closeable {

    /**
     * 编号
     */
    private final String code;

    public Door(String code) {
        this.code = code;
    }

    @Override
    public void close() throws IOException {
        PrintUtil.log("{}门已关闭", this.code);
    }
}
